package com.dlc.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.bean.dto.wukong.ChannelDTO;
import com.dlc.shop.bean.dto.wukong.RegisterOrLoginDTO;
import com.dlc.shop.bean.dto.wukong.SetUnreadDTO;
import com.dlc.shop.bean.model.ImChannel;
import com.dlc.shop.bean.model.ShopDetail;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.enums.SysTypeEnum;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.wukongim.constant.WuKongConstant;
import com.dlc.shop.dao.ImChannelMapper;
import com.dlc.shop.service.ImChannelService;
import com.dlc.shop.service.ShopDetailService;
import com.dlc.shop.wukongim.service.WuKongImService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 频道关联表
 * @author TRACK
 */
@Service
@AllArgsConstructor
public class ImChannelServiceImpl extends ServiceImpl<ImChannelMapper, ImChannel> implements ImChannelService {

    private final ImChannelMapper imChannelMapper;
    private final WuKongImService wuKongImService;
    private final ShopDetailService shopDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createChannel(ImChannel imChannel, ChannelDTO channelDTO, String nickName) {
        ImChannel dbData = imChannelMapper.selectById(imChannel.getChannelId());
        if (Objects.nonNull(dbData)) {
            throw new YamiShopBindException("频道已创建");
        }
        String prefix = Objects.equals(imChannel.getShopId(), Constant.PLATFORM_SHOP_ID) ? WuKongConstant.SYS : WuKongConstant.SHOP;
        // 不把用户添加进去
        List<String> ids = channelDTO.getSubscribers().stream()
                .map(s -> s.substring(prefix.length()).split(WuKongConstant.UNDERLINE)[0]).collect(Collectors.toList());
        ids.remove(0);
        // 拼接订阅者
        String subscriber = StrUtil.join(StrUtil.COMMA, ids);
        imChannel.setSubscribers(subscriber);
        imChannelMapper.insert(imChannel);
        // 发送创建频道请求
        Iterator<String> iterator = channelDTO.getSubscribers().iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if (item.startsWith(WuKongConstant.USER)) {
                continue;
            }
            if (!Objects.equals(item.substring(prefix.length()).split(WuKongConstant.UNDERLINE)[0], imChannel.getEmployeeId().toString())) {
                iterator.remove();
            }
        }
        wuKongImService.createChannel(channelDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateChannel(ImChannel imChannel, String uid, String nickName) {
        String channelId = imChannel.getChannelId();
        ImChannel dbImChannel = imChannelMapper.selectById(channelId);
        if (Objects.isNull(dbImChannel)) {
            throw new YamiShopBindException("频道不存在");
        }
        List<Long> subscribers = Arrays.stream(dbImChannel.getSubscribers().split(StrUtil.COMMA))
                .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        Boolean shouldAdd = !subscribers.contains(imChannel.getEmployeeId());
        if (shouldAdd) {
            subscribers.add(imChannel.getEmployeeId());
            imChannel.setSubscribers(StrUtil.join(StrUtil.COMMA, subscribers));
        }
        // 更新频道
        imChannelMapper.update(imChannel);
        // 添加订阅者
        wuKongImService.addSubscriber(channelId, uid);
        // 移除原订阅者
        String removeUid = dbImChannel.getShopId() == Constant.PLATFORM_SHOP_ID ? WuKongConstant.getSysUid(dbImChannel.getEmployeeId())
                : WuKongConstant.getShopUid(dbImChannel.getEmployeeId(), dbImChannel.getShopId());
        wuKongImService.removeSubscriber(channelId, removeUid);
        // 发送一条转接消息
        wuKongImService.sendTransferMessage(channelId, nickName, uid);
    }

    @Override
    public ImChannel getByChannelId(String channelId) {
        return imChannelMapper.selectById(channelId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeSubscribers(Long employeeId, Long shopId, Integer isDelete, String nickName) {
        List<ImChannel> imChannels = imChannelMapper.listChannelByEmployeeId(employeeId, shopId, null);
        if (CollUtil.isEmpty(imChannels)) {
            return;
        }
        // 该客服参与的频道（移除订阅者）
        List<ImChannel> joinChannels = new ArrayList<>();
        // 获取超管id
        Long adminId;
        String uid;
        String addUid;
        if (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
            adminId = Constant.SUPER_ADMIN_ID;
            uid = WuKongConstant.getSysUid(employeeId);
            addUid = WuKongConstant.getSysUid(adminId);
        } else {
            ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
            adminId = Long.parseLong(shopDetail.getUserId());
            uid = WuKongConstant.getShopUid(employeeId, shopId);
            addUid = WuKongConstant.getShopUid(adminId, shopId);
        }
        for (ImChannel imChannel : imChannels) {
            List<Long> subscribers = Arrays.stream(imChannel.getSubscribers().split(StrUtil.COMMA)).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            for (Long subscriber : subscribers) {
                if (Objects.equals(subscriber, employeeId)) {
                    if (Objects.equals(imChannel.getEmployeeId(), employeeId)) {
                        imChannel.setEmployeeId(adminId);
                    }
                    if (isDelete == 1) {
                        subscribers.remove(employeeId);
                        imChannel.setSubscribers(StrUtil.join(StrUtil.COMMA, subscribers));
                    }
                    joinChannels.add(imChannel);
                    break;
                }
            }
        }
        if (CollUtil.isNotEmpty(joinChannels)) {
            imChannelMapper.updateImChannelBatch(joinChannels);
            for (ImChannel imChannel : joinChannels) {
                // 添加超管
                wuKongImService.addSubscriber(imChannel.getChannelId(), addUid);
                // 移除订阅者
                wuKongImService.removeSubscriber(imChannel.getChannelId(), uid);
                // 更新群资料
                wuKongImService.sendChangeUserInfoMessage(imChannel.getChannelId());
                // 发送一条转接消息
                wuKongImService.sendTransferMessage(imChannel.getChannelId(), nickName, addUid);
            }
        }
        // 将用户踢出设备
        wuKongImService.deviceQuit(new RegisterOrLoginDTO(uid, -1));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setUnread(SetUnreadDTO setUnreadDTO, Integer userType) {
        updateSeq(setUnreadDTO, userType);
        wuKongImService.setUnread(setUnreadDTO);
        // 消除红点cmd指令
        wuKongImService.sendDeleteUnreadInfoMessage(setUnreadDTO.getChannel_id(), userType);
    }

    @Override
    public void updateSeq(SetUnreadDTO setUnreadDTO, Integer userType) {
        String channelId = setUnreadDTO.getChannel_id();
        Long maxSeq = setUnreadDTO.getMaxSeq();
        ImChannel imChannel = new ImChannel();
        imChannel.setChannelId(channelId);
        if (Objects.equals(userType, SysTypeEnum.ORDINARY.value())) {
            imChannel.setUserReadSeq(maxSeq);
        } else {
            imChannel.setShopReadSeq(maxSeq);
        }
        imChannelMapper.updateMaxSeq(imChannel);
        // 发送用户已读的消息给对方
        wuKongImService.sendReadMessage(channelId, maxSeq, userType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAuto(String channelId, Integer sendAutoReply, String content, String uid) {
        imChannelMapper.updateAuto(channelId, sendAutoReply);
        if (Objects.equals(sendAutoReply, 1)) {
            // 发送自动回复消息
            wuKongImService.sendAutoReplyMessage(channelId, content, uid);
        }
    }

    @Override
    public List<String> listChannelByShopId(Long shopId) {
        return imChannelMapper.listChannelByShopId(shopId);
    }

    @Override
    public List<ImChannel> listChannelByUserId(String userId) {
        return imChannelMapper.listChannelByUserId(userId);
    }

    @Override
    public void updateMember(Long employeeId, Long shopId, String userId) {
        List<ImChannel> imChannels = imChannelMapper.listChannelByEmployeeId(employeeId, shopId, userId);
        if (CollUtil.isEmpty(imChannels)) {
            return;
        }
        for (ImChannel imChannel : imChannels) {
            // 更新群资料
            wuKongImService.sendChangeUserInfoMessage(imChannel.getChannelId());
        }
    }
}
